package com.inspectortime.admin;

import java.io.Serializable;

import javax.servlet.http.HttpServletRequest;

import com.inspectortime.domain.Employee;
import com.inspectortime.domain.InspectorCompany;
import com.inspectortime.domain.User;
import com.inspectortime.repository.Repository;

/**
 * Consolidates all interractions and attribute keys used with the HttpSession
 * 
 * @author mkvalsvik
 * 
 */
public class HttpSessionUtils {

	private HttpSessionUtils() {
	}

	public static final String SESSION_ATTRIBUTE_USER_ID = "userId";
	public static final String SESSION_ATTRIBUTE_USERNAME = "userName";

	public static void removeLoggedInUser(HttpServletRequest request) {
		request.getSession().setAttribute(SESSION_ATTRIBUTE_USER_ID, null);
		request.getSession().setAttribute(SESSION_ATTRIBUTE_USERNAME, null);
	}
	
	public static void storeLoggedInUser(HttpServletRequest request, User user) {
		request.getSession().setAttribute(SESSION_ATTRIBUTE_USER_ID, user.getId());
		request.getSession().setAttribute(SESSION_ATTRIBUTE_USERNAME, user.getUserName());
	}
	
	public static boolean isUserLoggedIn(HttpServletRequest request) throws LoggedInUserNotFoundException {
		Serializable userId = (Serializable) request.getSession().getAttribute(
				SESSION_ATTRIBUTE_USER_ID);
		if (userId == null) {
			return false;
		}
		return true;
	}
	
	public static Serializable retrieveLoggedInUserId(HttpServletRequest request) throws LoggedInUserNotFoundException {
		Serializable userId = (Serializable) request.getSession().getAttribute(
				SESSION_ATTRIBUTE_USER_ID);
		if (userId == null) {
			throw new LoggedInUserNotFoundException(
					"Logged in user not found in http session.");
		}
		return userId;
	}
	
	/**
	 * Retrieve user from session and then re-load that user to ensure he is
	 * properly bound to Hibernate session
	 * 
	 * TODO: Consider if there are efficiencies to be gained by merging with
	 * current session instead of re-loading
	 */
	public static User retrieveLoggedInUser(
			HttpServletRequest request, Repository repository)
			throws LoggedInUserNotFoundException {
		User freshUser = repository.loadUser(retrieveLoggedInUserId(request));
		if (freshUser == null) {
			throw new LoggedInUserNotFoundException(
					"User in http session was not found in database.");
		}
		return freshUser;
	}
	
	/*
	public static Inspector retrieveLoggedInInspector(
			HttpServletRequest request, Repository repository)
	throws LoggedInUserNotFoundException {
		User user = HttpSessionUtils.retrieveLoggedInUser(request, repository);
		if (!(user instanceof Inspector)) {
			throw new LoggedInUserNotFoundException("Logged user is not an inspector, operation not allowed.");
		}
		Inspector inspector = (Inspector) user;
		return inspector;
	}
	*/
	
	public static Employee retrieveLoggedInEmployee(
			HttpServletRequest request, Repository repository)
	throws LoggedInUserNotFoundException {
		User user = HttpSessionUtils.retrieveLoggedInUser(request, repository);
		if (!(user instanceof Employee)) {
			throw new LoggedInUserNotFoundException("Logged user is not an employee, operation not allowed.");
		}
		return (Employee) user;
	}
	
	/**
	 * Gets the company associated with the logged in user
	 * @param request
	 * @param repository
	 * @return
	 * @throws LoggedInUserNotFoundException
	 */
	public static InspectorCompany retrieveLoggedInCompany(
			HttpServletRequest request, Repository repository)
	throws LoggedInUserNotFoundException {
		User user = HttpSessionUtils.retrieveLoggedInUser(request, repository);
		if (!(user instanceof Employee)) {
			throw new LoggedInUserNotFoundException("Logged user is not an employee, operation not allowed.");
		}
		return ((Employee) user).getCompany();
	}

}
